import { AfterViewInit, Component, OnInit, TemplateRef } from '@angular/core';
import { FormBuilder, FormControl, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal';
import { NzTableQueryParams } from 'ng-zorro-antd/table';
import { BehaviorSubject } from 'rxjs';
import { Consts } from 'src/app/consts/consts';
import { EditMode } from 'src/app/models/enums/edit-mode.enum';
import { DeptQueryParam } from 'src/app/models/param/dept-query.param';
import { DeptDto } from 'src/app/models/sys/dept.dto';
import { MenuDto } from 'src/app/models/sys/menu.dto';
import { ApiService } from 'src/app/services/api.service';
import { ContentHeaderService } from 'src/app/services/content-header.service';

const DEPT_NAME = 'deptName';
const ENABLED = 'enabled';

@Component({
  selector: 'app-dept',
  templateUrl: './dept.component.html',
  styleUrls: ['./dept.component.less']
})
export class DeptComponent implements OnInit, AfterViewInit {
  searchForm!: UntypedFormGroup;
  submitted = false;

  // Dept Table
  depts: DeptDto[] = [];
  pageIndex = 1;
  pageSize = 10;
  total = 0;

  // Modal
  modeSubject = new BehaviorSubject<{ mode: EditMode, dept?: DeptDto, parentId?: number }>({ mode: EditMode.ADD, dept: undefined, parentId: undefined });
  
  // 对话框title
  editTitle?: string;
  deptName?: string;

  // 详情
  deptSubject = new BehaviorSubject<DeptDto>(new DeptDto());

  mapOfExpandedData: { [key: number]: DeptDto[] } = {};

  constructor(private _api: ApiService,
    private _fb: FormBuilder,
    private _modal: NzModalService,
    private _message: NzMessageService,
    private _contentHeader: ContentHeaderService) { }

  ngAfterViewInit(): void {
    setTimeout(() => {
      this._contentHeader.header.next('部门管理');
    });
  }

  ngOnInit(): void {
    console.log('dept on init called');
    this.createSearchForm();
    this.onSearch();
  }

  createSearchForm() {
    this.searchForm = this._fb.group({});
    this.searchForm.addControl(DEPT_NAME, new UntypedFormControl('', [Validators.maxLength(20)]));
    this.searchForm.addControl(ENABLED, new UntypedFormControl(''));
  }

  get fm() {
    return this.searchForm.controls;
  }

  onSearch() {
    this.submitted = true;
    if (!this.searchForm.valid) {
      return;
    }

    const param = new DeptQueryParam();
    param.deptName = this.searchForm.get('deptName')?.value;
    param.enabled = this.searchForm.get('enabled')?.value;
    param.pageNum = this.pageIndex;
    param.pageSize = this.pageSize;
    this._api.getDeptTree(param).subscribe((resp) => {
      if (resp.code == Consts.RESP_OK && resp.data) {
        this.depts = resp.data;
        this.total = resp.total;

        console.log('convert depts to table tree');
        this.mapOfExpandedData = {};
        this.depts.forEach(item => {
          this.mapOfExpandedData[item.deptId] = this.convertTreeToList(item);
        });

        this.submitted = false;
      }
    });
  }

  onCreate(tplTitle: TemplateRef<object>, tplContent: TemplateRef<object>, parentId?: number) {
    this.editTitle = '创建部门';
    this.deptName = undefined;
    this.resetModal();

    this._modal.create({
      nzTitle: tplTitle,
      nzContent: tplContent,
      nzFooter: null,
      nzMaskClosable: false,
      nzClosable: false,
      nzWidth: 800,
      nzOnOk: () => {
        console.log('dept added');
      }
    });

    this.modeSubject.next({ mode: EditMode.ADD, dept: undefined, parentId: parentId });
  }

  onUpdate(tplTitle: TemplateRef<object>, tplContent: TemplateRef<object>, dept: DeptDto) {
    console.log('OnUpdate Dept');
    this.editTitle = '编辑部门';
    this.deptName = dept.deptName;
    this.resetModal();

    this._modal.create({
      nzTitle: tplTitle,
      nzContent: tplContent,
      nzFooter: null,
      nzMaskClosable: false,
      nzClosable: false,
      nzWidth: 800,
      nzOnOk: () => {
        console.log('dept added');
      }
    });

    this.modeSubject.next({ mode: EditMode.EDIT, dept: dept, parentId: undefined });
  }

  onDetail(tplTitle: TemplateRef<object>, tplContent: TemplateRef<object>, dept: DeptDto) {
    this.editTitle = '部门详情';

    this._modal.create({
      nzTitle: tplTitle,
      nzContent: tplContent,
      nzFooter: null,
      nzMaskClosable: false,
      nzClosable: false,
      nzWidth: 800,
      nzOnOk: () => {
        console.log('groupType detail');
      }
    });

    this.deptSubject.next(dept);
  }

  onDelete(id: number) {
    console.log(`To delete dept of ${id}`);
    this._api.deleteDept(id).subscribe((resp) => {
      if (resp.code == Consts.RESP_OK) {
        this._message.info("删除部门成功");
        this.onSearch();
      } else {
        this._message.warning("删除部门失败：" + resp.message);
      }
    });
  }

  onReset() {
    this.searchForm.get('deptName')?.setValue(undefined);
    this.searchForm.get('enabled')?.setValue(undefined);
    this.submitted = false;
  }

  resetModal() {
    this.editTitle = "添加功能";
  }

  onCreateBelow(tplTitle: TemplateRef<object>, tplContent: TemplateRef<object>, dept: DeptDto) {
    this.onCreate(tplTitle, tplContent, dept.deptId);
  }

  // Tree ops
  convertTreeToList(root: DeptDto): DeptDto[] {
    const stack: DeptDto[] = [];
    const array: DeptDto[] = [];
    const hashMap = {};
    stack.push({ ...root, level: 0, expand: false });

    while (stack.length !== 0) {
      const node = stack.pop()!;
      this.visitNode(node, hashMap, array);
      if (node.children) {
        for (let i = node.children.length - 1; i >= 0; i--) {
          stack.push({ ...node.children[i], level: node.level! + 1, expand: false, parent: node });
        }
      }
    }

    return array;
  }

  visitNode(node: DeptDto, hashMap: { [key: number]: boolean }, array: DeptDto[]): void {
    if (!hashMap[node.deptId]) {
      hashMap[node.deptId] = true;
      array.push(node);
    }
  }

  collapse(array: DeptDto[], data: DeptDto, $event: boolean): void {
    if (!$event) {
      if (data.children) {
        data.children.forEach(d => {
          const target = array.find(a => a.deptId === d.deptId)!;
          target.expand = false;
          this.collapse(array, target, false);
        });
      } else {
        return;
      }
    }
  }

  onAddDeptEvent(result: boolean) {
    console.log(`add dept result ${result}`);

    this._modal.closeAll();
    if (result) {
      this.onSearch();
    }
  }

  onPageParamChange(params: NzTableQueryParams) {
    this.pageIndex = params.pageIndex;
    this.pageSize = params.pageSize;
    this.onSearch();
  }

  onDetailEvent(result: boolean) {
    this._modal.closeAll();
    console.log(`${result}`);
  }
}
